module Hexena.Obscure ( interestingRollingDifference
                      , obscureDisplay
                      , pixl
                      ) where

-- not really useful, this maybe works for documents with embedded encrypted exes...

-- TODO: Can produce nice graphs but other than that it is mostly
-- useless. Should be cleaned up and put into the report anyways.

import qualified Data.ByteString.Lazy as BL
import Data.List (concatMap,groupBy,filter)
import qualified Graphics.UI.SDL as S
import qualified Graphics.UI.SDL.Primitives as S

rollingDifference :: (Integral a) => [a] -> [Int]
rollingDifference (x:zs@(y:_)) = (fromIntegral y) - (fromIntegral x) : rollingDifference zs
rollingDifference _ = []

getRollingRuns :: [Int] -> [[(Int, Int)]]
getRollingRuns = filter (not . null . tail) . groupBy (\(_,b) (_,d) -> b == d) . zip [0..]

getInterestingRuns :: [[(Int, Int)]] -> [(Int, Int, Int)]
getInterestingRuns = map simplify
    where simplify :: [(Int, Int)] -> (Int, Int, Int)
          simplify x@((p,v):_) = (p, length x, v)

interestingRollingDifference :: BL.ByteString -> [(Int, Int, Int)]
interestingRollingDifference = getInterestingRuns . getRollingRuns . rollingDifference . BL.unpack

pixl :: S.Surface -> Int -> Int -> Int -> IO Bool
pixl s x y v = S.pixel s (fromIntegral x) (fromIntegral y) $ S.Pixel $ col v
    where col x | x < 0 = 0xff333390
                | x > 0 = 0x33ff3390
                | otherwise = 0x4444ff8c

obscureDisplay :: BL.ByteString -> IO (S.Surface)
obscureDisplay dat = do
  S.init []
  let i = interestingRollingDifference dat
      i1 = Data.List.filter (\(_,x,_) -> x > 2) i
      -- i2 = map (\(p,l,v) -> (p`div`2, l`div`2, v)) i1
      i3 = Data.List.concatMap (\(p,l,v) -> zip [p..p+l] $ repeat v) i1
      lw = 512
  s <- S.setVideoMode lw 900 32 []
  mapM_ (\(p,v) -> pixl s (p `mod` lw) (p `div` lw) v) i3
  S.flip s
  print $ filter (\(_,_,x) -> x>0) i1
  return s

